package com.example.quartz.project.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.quartz.common.Tool.MyselfUtils;
import com.example.quartz.project.dto.QuartzDto;
import com.example.quartz.project.mapper.QuartzMapper;
import com.example.quartz.project.po.Quartz;
import com.example.quartz.project.service.QuartzService;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 打小就爱笑捏
 * @date 2019/11/11
 */
@Service
public class QuartzServiceImpl extends ServiceImpl<QuartzMapper, Quartz> implements QuartzService {
    @Autowired
    private QuartzMapper quartzMapper;
    @Resource
    private Scheduler scheduler;
    @Resource
    private MyselfUtils myselfUtils;

    @Override
    public Object getAllByPage(QuartzDto dto, Page page, String orderList) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (ObjectUtils.isNotEmpty(dto.getJobClassName())) {
            queryWrapper.like("job_class_name", dto.getJobClassName());
        }
        if (!ObjectUtils.isNotEmpty(orderList)) {
            List list = myselfUtils.spaceByComma(orderList);/*逗号分割*/
            queryWrapper.orderByDesc(list);
        }
        Page userIPage = quartzMapper.selectPage(page, queryWrapper);
        Map<String, Object> result = new LinkedHashMap<>(4);
        result.put("code", "0");
        result.put("msg", "success");
        result.put("data", userIPage.getRecords());
        result.put("count", userIPage.getRecords().size());
        return result;
    }

    @Override
    public Quartz add(Quartz quartz) throws Exception {
        if (quartz.getStatus().equals(0)) {
            this.schedulerAdd(quartz.getJobClassName().trim(), quartz.getCronExpression().trim(), quartz.getParameter());
        }
        int insert = getBaseMapper().insert(quartz);
        if (insert > 0) {
            return quartz;
        }
        return null;
    }


    @Override
    public boolean resumeJob(Quartz quartz) throws Exception {
        schedulerDelete(quartz.getJobClassName().trim());
        schedulerAdd(quartz.getJobClassName().trim(), quartz.getCronExpression().trim(), quartz.getParameter());
        quartz.setStatus(0);
        return this.updateById(quartz);
    }


    @Override
    public boolean edit(Quartz quartz) throws Exception {
        if (ObjectUtils.isEmpty(quartz.getId())) {
            return false;
        }
        if (quartz.getStatus().equals(0)) {
            schedulerDelete(quartz.getJobClassName().trim());
            schedulerAdd(quartz.getJobClassName().trim(), quartz.getCronExpression().trim(), quartz.getParameter());
        } else {
            scheduler.pauseJob(JobKey.jobKey(quartz.getJobClassName().trim()));
        }
        return this.updateById(quartz);
    }


    @Override
    public int delete(Quartz job) {
        schedulerDelete(job.getJobClassName().trim());

        return getBaseMapper().deleteById(job.getId());
    }


    private void schedulerAdd(String jobClassName, String cronExpression, String parameter) throws Exception {
        try {
            // 启动调度器
            scheduler.start();

            // 构建job信息
            JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName).usingJobData("parameter", parameter).build();

            // 表达式调度构建器(即任务执行的时间)
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

            // 按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build();

            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            try {
                throw new Exception("创建定时任务失败", e);
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        } catch (RuntimeException e) {
            throw new Exception(e.getMessage(), e);
        } catch (Exception e) {
            throw new Exception("后台找不到该类名:" + jobClassName, e);
        }
    }


    private void schedulerDelete(String jobClassName) {
        try {
            /*使用给定的键暂停Trigger 。*/
            scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
            /*从调度程序中删除指示的Trigger */
            scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
            /*从 Scheduler 中删除已识别的Job - 以及任何关联的Trigger */
            scheduler.deleteJob(JobKey.jobKey(jobClassName));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            try {
                throw new Exception("删除定时任务失败");
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
    }

    private static Job getClass(String classname) throws Exception {
        Class<?> class1 = Class.forName(classname);
        return (Job) class1.newInstance();
    }


    @Override
    public void test(String param, Integer sum) {
        System.out.println("第" + sum + "次--------带参数--------" + param);
    }

}
